package com.mybed.crm.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mybed.crm.common.enums.HttpCodeEnum;
import com.mybed.crm.exception.BaseException;
import com.mybed.crm.mapper.DeptMapper;
import com.mybed.crm.mapper.RoleMapper;
import com.mybed.crm.mapper.UserMapper;
import com.mybed.crm.pojo.dto.PageUserDto;
import com.mybed.crm.pojo.pojo.Dept;
import com.mybed.crm.pojo.pojo.Role;
import com.mybed.crm.pojo.pojo.User;
import com.mybed.crm.pojo.pojo.UserDownLoad;
import com.mybed.crm.pojo.vo.DeptVo;
import com.mybed.crm.pojo.vo.RoleVo;
import com.mybed.crm.pojo.vo.UserInfoVo;
import com.mybed.crm.pojo.vo.UserVo;
import com.mybed.crm.result.PageResult;
import com.mybed.crm.result.Result;
import com.mybed.crm.result.ResultP;
import com.mybed.crm.result.UserResult;
import com.mybed.crm.service.UserService;
import com.mybed.crm.utils.thread.UserThreadLocalUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
    @Autowired
    private RoleMapper roleMapper;
    @Autowired
    private DeptMapper deptMapper;
    @Autowired
    private UserMapper userMapper;

    /**
     * 获得用户信息
     * @return
     */
    @Override
    public UserInfoVo getInfo() {
        String userId = UserThreadLocalUtil.getUser();
        User user = getById(userId);
        UserVo userVo=new UserVo();
        BeanUtils.copyProperties(user,userVo);
        String roleIds = user.getRoleIds();
        List<String> roleids = Arrays.asList(roleIds.split(","));
        List<Integer> collected = roleids.stream().map(o -> Integer.valueOf(o)).collect(Collectors.toList());
        List<Role> roles = roleMapper.selectBatchIds(roleids);
        List<RoleVo> list = roles.stream().map(o -> {
            RoleVo vo = new RoleVo();
            BeanUtils.copyProperties(o, vo);
            return vo;
        }).collect(Collectors.toList());
        Dept dept = deptMapper.selectById(user.getDeptId());
        DeptVo deptVo=new DeptVo();
        BeanUtils.copyProperties(dept,deptVo);
        userVo.setDept(deptVo);
        userVo.setRoleIds(collected);
        userVo.setRoles(list);
        UserInfoVo vo=new UserInfoVo();
        vo.setUser(userVo);
        return vo;
    }

    /**
     * 转派管理选择部门后显示的人员
     * @param deptId
     * @return
     */

    @Override
    public Result listselect(Integer deptId) {
        List<Integer> listIds = selectUserIds(deptId);
        List<User> byIds=new ArrayList<>();
        if(!CollectionUtils.isEmpty(listIds)){
            byIds= list(Wrappers.<User>lambdaQuery().in(User::getDeptId,listIds));
        }

        return Result.success(byIds);
    }

    @Override
    public PageResult listUser(PageUserDto dto) {
        LambdaQueryWrapper<User> wrapper=new LambdaQueryWrapper<>();
        wrapper.like(StringUtils.hasLength(dto.getUserName()), User::getUserName,dto.getUserName());
        wrapper.like(StringUtils.hasLength(dto.getPhonenumber()), User::getPhonenumber,dto.getPhonenumber());
        wrapper.eq(dto.getStatus()!=null, User::getStatus,dto.getStatus());
        if(dto.getParams()!=null){
            wrapper.between(StringUtils.hasLength(dto.getParams().get("beginTime"))&&StringUtils.hasLength(dto.getParams().get("endTime")), User::getCreateTime,dto.getParams().get("beginTime"),dto.getParams().get("endTime"));
        }
        if(dto.getDeptId()!=null){
            List<Integer> list = selectUserIds(dto.getDeptId());
            wrapper.in(User::getUserId,list);
        }
        IPage<User> page=new Page<>(dto.getPageNum(),dto.getPageSize());
        IPage<User> iPage=page(page,wrapper);
        if(!CollectionUtils.isEmpty(iPage.getRecords())){
            List<Integer> DeptIds = iPage.getRecords().stream().map(User::getDeptId).collect(Collectors.toList());
            List<Dept> depts = deptMapper.selectBatchIds(DeptIds);
            Map<Integer, DeptVo> deptMap = depts.stream().map(o->{
                DeptVo vo=new DeptVo();
                BeanUtils.copyProperties(o,vo);
                return vo;
            }).collect(Collectors.toMap(DeptVo::getDeptId, Function.identity()));
            List<User> records = iPage.getRecords();
            List<UserVo> collect = records.stream().map(o -> {
                UserVo vo = new UserVo();
                BeanUtils.copyProperties(o, vo);
                vo.setDept(deptMap.get(vo.getDeptId()));
                return vo;
            }).collect(Collectors.toList());
            PageResult result=new PageResult();
            result.insertData(iPage);
            result.setRows(collect);
            return result;
        }else {
            PageResult result=new PageResult();
            result.insertData(iPage);
            return result;
        }


    }

    /**
     * 查询用户详情
     * @param id
     * @return
     */
    @Override
    public UserResult updateUser(Integer id) {
        User user = getById(id);
        UserVo userVo = new UserVo();
        BeanUtils.copyProperties(user,userVo);
        List<Integer> roleIds;
        List<RoleVo> roleVos;
        if(StringUtils.hasLength(user.getRoleIds())){
            roleIds = Arrays.stream(user.getRoleIds().split(",")).map(Integer::parseInt).collect(Collectors.toList());
            List<Role> roles = roleMapper.selectBatchIds(roleIds);
            roleVos = roles.stream().map(o->{
                RoleVo roleVo = new RoleVo();
                BeanUtils.copyProperties(o,roleVo);
                if(StringUtils.hasLength(o.getDeptIds()))
                roleVo.setDeptIds(Arrays.stream(o.getDeptIds().split(",")).map(Integer::parseInt).collect(Collectors.toList()));
                if(StringUtils.hasLength(o.getMenuIds()))
                roleVo.setMenuIds(Arrays.stream(o.getMenuIds().split(",")).map(Integer::parseInt).collect(Collectors.toList()));
                return roleVo;
            }).collect(Collectors.toList());
        }else {
            roleIds = new ArrayList<>();
            roleVos=new ArrayList<>();
        }
        userVo.setRoleIds(roleIds);
        userVo.setRoles(roleVos);
        Dept dept = deptMapper.selectById(user.getDeptId());
        DeptVo deptVo = new DeptVo();
        BeanUtils.copyProperties(dept,deptVo);
        userVo.setDept(deptVo);
        List<Role> roles = roleMapper.selectList(null);
        UserResult result=new UserResult();
        result.setData(userVo);
        result.setRoleIds(roleIds);
        result.setRoles(roles);
        result.setCode(HttpCodeEnum.SUCCESS.getCode());
        result.setMsg(HttpCodeEnum.SUCCESS.getErrorMessage());
        return result;
    }

    @Override
    public void updateByUser(UserVo vo) {
        /*User one = getOne(Wrappers.<User>lambdaQuery().eq(User::getUserName, vo.getUserName()));
        if(one !=null ){
            throw new BaseException("用户名已经存在");
        }*/
        User By = getById(UserThreadLocalUtil.getUser());
        User user=new User();
        BeanUtils.copyProperties(vo,user);
        user.setUpdateBy(By.getUserName());
        user.setUpdateTime(LocalDateTime.now());
        user.setRoleIds(StringUtils.collectionToCommaDelimitedString(vo.getRoleIds()));
        updateById(user);
    }

    /**
     * 用户管理的导出
     * @return
     */
    @Override
    public List<UserDownLoad> selectUserDownload() {
        List<UserDownLoad> users = userMapper.selectUserDownload();
        return users;
    }

    /**
     * 递归查找部门的所有人员
     * @param deptId
     * @param set
     * @param deptMap
     * @param listIds
     */
    public void f(Integer deptId,Set<Integer> set,Map<Integer, Dept> deptMap,List<Integer> listIds){
        for (Integer i : set) {
            if(deptMap.get(i).getParentId()==deptId){
                f(i,set,deptMap,listIds);
            }
        }
        listIds.add(deptId);
    }
    public List<Integer> selectUserIds(Integer deptId){
        List<Dept> depts = deptMapper.selectList(null);
        Map<Integer, Dept> deptMap = depts.stream().collect(Collectors.toMap(Dept::getDeptId, Function.identity()));
        Set<Integer> set = deptMap.keySet();
        List<Integer> listIds=new ArrayList<>();
        f(deptId,set,deptMap,listIds);
        return  listIds;
    }


}
